package com.fzrskj.cloud.free.core.filter;

import com.fzrskj.cloud.free.core.AppStatus;
import com.fzrskj.cloud.free.core.tool.*;
import com.fzrskj.cloud.free.core.utils.CloudContextUtils;
import com.fzrskj.cloud.free.sys.utils.AgentAccountUtils;
import com.fzrskj.cloud.free.sys.vo.AgentAccountMessageVo;
import com.fzrskj.cloud.free.user.bean.UserAccountView;
import com.fzrskj.cloud.free.user.utils.UserAccountUtils;
import ms.core.consts.Consts;
import ms.core.consts.SysErr;
import ms.core.support.Session;
import ms.core.support.UploadParam;
import ms.core.tool.*;
import org.apache.commons.collections.map.HashedMap;
import org.apache.http.HttpStatus;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * FileCrossFilter.
 *
 * @author zj.
 *         Created on 2019/8/28 0028.
 */
public class FileCrossFilter implements Filter {
    public FileCrossFilter() {
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest)request;
        HttpServletResponse resp = (HttpServletResponse)response;

        //设置debug
        AppStatus.setDebug(Boolean.valueOf(SystemConfig.getProper("debug")));

        //代理信息设置;
        AgentAccountMessageVo messageVo = new AgentAccountMessageVo();
        if (!AgentAccountUtils.setAgentInfo(req, messageVo)) {
            resp.setStatus(403);
            String ret = XmlCodeParser.formatResultTips(false, messageVo.getCode(), messageVo.getMessage());
            CResponseTool.doResponseText(resp, ret);
            return;
        }

        String uri = req.getRequestURI();
        String sid = CCookieTool.getSessionId(req);
        Session session = CSessionTool.getSessionCloud(sid);
        if (null == session) {
            CSessionTool.newSessionCloud(sid);
            session = CSessionTool.getSessionCloud(sid);
        }

        //如果是管理员直接放行
        if (session.getUtype() == 0 && CloudContextUtils.getAgentId() == 0) {
        } else {
            //旧上传地址兼容处理
            String compatibleRule = "/upload/([a-z0-9]{32}).(jpg|png|gif|bmp|jpeg)";
            Pattern patternCompatible = Pattern.compile(compatibleRule);
            Matcher matchCompatible = patternCompatible.matcher(uri);
            if (!matchCompatible.find()) {
                if (!uri.startsWith("/upload/public")) {
                    Map<String, UploadParam> uploadParams = CXmlUploadParser.getUploadParams();
                    boolean match = false;
                    for (UploadParam uploadParam : uploadParams.values()) {
                        if (uploadParam.getSavePath().startsWith("/public")) {
                            continue;
                        }

                    /*String checkPath = "/upload" + uploadParam.getSavePath().replaceAll("\\{uid}", String.valueOf(CloudContextUtils.getSession().getUID())) + "/";

                    if (uri.startsWith(checkPath)) {
                        match = true;
                        break;
                    }
*/
                        //匹配资源对应的用户ID
                        String rule = uploadParam.getSavePath().replaceAll("\\{uid}", "([0-9]+)") + "/";
                        Pattern pattern = Pattern.compile(rule);
                        Matcher m = pattern.matcher(uri);
                        Integer uid = -99;
                        if (m.find()) {
                            String matchString = m.group(0);
                            String ruleSub = "/([0-9]+)/";
                            Pattern patternSub = Pattern.compile(ruleSub);
                            Matcher sub = patternSub.matcher(matchString);
                            if (sub.find()) {
                                String uidString = sub.group(0).replaceAll("/", "");
                                uid = Integer.valueOf(uidString);
                            }
                        }
                        //如果是本用户访问，放行
                        if (uid == CloudContextUtils.getSession().getUID()) {
                            match = true;
                            break;
                        }

                        //如果是代理管理员，判断图径用户是否属于自己，如果是，测允许访问
                        if (session.getUtype() == 0 && uid > 0) {
                            //是代理账号会员账号
                            if (uid.equals(CloudContextUtils.getAgentId())) {
                                match = true;
                                break;
                            }
                            //非代理会员账号
                            UserAccountUtils accountUtils = new UserAccountUtils();
                            UserAccountView view = accountUtils.queryUserAccountViewByUid(uid);
                            if (null != view && view.getAgentId() == CloudContextUtils.getSession().getUID()) {
                                match = true;
                                break;
                            }
                        }
                    }
                    if (!match) {
                        resp.setHeader("Content-Type", "application/json");
                        String error = XmlCodeParser.formatResultTips(false, SysErr.USER_NOT_LOGIN);
                        ResponseTool.doResponseText(resp, req, 403, error);
                        return;
                    }
                }
            }
        }

        //chain.doFilter(request, response);

        //读取文件并输出
        String tplPath = Consts.STATIC_PATH  + uri;
        File file = new File(tplPath);
        if (!file.exists()) {
            resp.setHeader("Content-Type", "application/json");
            String error = XmlCodeParser.formatResultTips(false, "RESOURCE NOT EXISTS", "资源不存在");
            ResponseTool.doResponseText(resp, req, 403, error);
            return;
        }

        //输出类型设置
        //后缀
        String ext = uri.substring(uri.lastIndexOf(".") + 1);
        if (this.contentTypeMap.containsKey(ext)) {
            resp.setHeader("Content-Type", this.contentTypeMap.get(ext));
        } else {
            resp.setHeader("Content-Type", "application/octet-stream");
        }
        resp.setStatus(HttpStatus.SC_OK);

        try {
            FileInputStream in = new FileInputStream(file);
            int n = 0;
            byte[] out = new byte[1024];
            while ((n = in.read(out)) != -1) {
                response.getOutputStream().write(out, 0, n);
            }
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    final Map<String, String> contentTypeMap = new HashedMap() {{
        this.put("jpg", "image/jpeg");
        this.put("jpeg", "image/jpeg");
        this.put("jpe", "image/jpeg");
        this.put("gif", "image/gif");
        this.put("png", "image/png");
        this.put("bmp", "application/x-bmp");
    }};

    @Override
    public void destroy() {

    }
}
